#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BLOCK_SIZE 64


typedef struct P
{
    int pag;
    int singnificenceBit;
    unsigned short block;
    int modify;
    unsigned short address;
    struct P *next;
}P;
typedef struct List
{
    char op[3];
    int pag;
    unsigned short move;
    struct List *next;
}List;

void sc(struct P *L)
{
    P *r;List *l;
    r = (P*)malloc(sizeof(P));
    r = L->next;

    printf("pag  singnificenceBit  block  modify  address\n");
    printf("--------------------------------------\n");
    while(r!= NULL){
        printf("%d    %d      	%d	%d	%d\n", r->pag, r->singnificenceBit, r->block, r->modify, r->address);
        r = r->next;
    }

}
void LRU1(int n,int a[])  //访问的页在栈中时，还应调整页从当前位置到栈顶。
{
    for(int i=0;i<4;i++)
    {
        if(a[i]==n)
            for(int j=i;j>0;j--){
                a[j] = a[j-1];
            }
        a[0] = n;

    }
}
int LRU2(int n,int a[])//当栈满需要淘汰时，操作系统选择栈底的元素淘汰，其他元素向下移动一个位置，将新调入页放HEAD指示的栈顶。
{
    int k = a[3];
    for(int i = 4-1;i>0;i--)
        a[i] = a[i-1];
    a[0] = n;
    return k;
}
void zh(P *L, int n, int m){
    P *s;
    s = (P*)malloc(sizeof(P));
    s = L->next;
    while(s!=NULL){
        if(s->pag == n)
            s->singnificenceBit = 0;
        if(s->pag == m)
            s->singnificenceBit = 1;
        s = s->next;
    }
}
int main(int argc,char *argv[])
{
    // 文件
    char *f1,*f2;
    f1 = argv[1];
    FILE *fp1 = fopen(f1, "r");
    f2 = argv[2];
    FILE *fp2 = fopen(f2, "r");
    if(!freopen(f1,"r",stdin)){
        fprintf(stderr,"could not redirect stdin from file %s\n",f1);
        exit(2);
    }
    if(!freopen(f2,"r",stdin)){
        fprintf(stderr,"could not redirect stdin from file %s\n",f2);
        exit(3);
    }
    if(argc!=3){
        fprintf(stderr,"参数数量错误，");
        exit(1);
    }


    P *pt,*p,*p1;
    pt = (P*)malloc(sizeof(P));
    p = (P*)malloc(sizeof(P));
    pt->next = NULL;
    p = pt;

    List *ol,*o,*o1;
    ol = (List*)malloc(sizeof(List));
    ol->next = NULL;
    o = (List*)malloc(sizeof(List));
    o = ol;

    int LRU[4];
    int a = 0;
    while(!feof(fp1))
    {
        p1 = (P*)malloc(sizeof(P));
        fscanf(fp1, "%d %d %hd %d %hd ", &p1->pag, &p1->singnificenceBit, &p1->block, &p1->modify, &p1->address);
        if(p1->singnificenceBit == 1)
        {
            LRU[a] = p1->pag;
            a++;
        }
        p->next = p1;
        p = p1;
    }
    p->next = NULL;

    while(!feof(fp2))
    {
        o1 = (List*)malloc(sizeof(List));
        fscanf(fp2, "%s %d %hd ", &o1->op[0], &o1->pag, &o1->move);
        o->next = o1;
        o = o1;
    }
    o->next = NULL;

    int free[4];//空闲块表
    for(int i =0;i<4;i++)
    {
        free[i] = 1;
    }

    List *r;
    P *l;
    l = (P*)malloc(sizeof(P));
    r = (List*)malloc(sizeof(List));
    r = ol->next;
    while(r!=NULL)
    {
        printf("操作：%s，页号：%d:", r->op, r->pag);

        l = pt->next;
        while(l->next!=NULL)
        {
            if(r->pag==l->pag)
                break;
            l = l->next;
        }
        if(l->singnificenceBit == 1){
            LRU1(l->pag,LRU);
            unsigned int absAddr = 0;
            absAddr = l->block*BLOCK_SIZE + r->move;
            printf("绝对地址:0x%04X\n",absAddr);


        }else{
            printf("该页号不在主存，产生缺页中断！\n");
            int h = LRU2(l->pag,LRU);
            printf("淘汰%d页，置换%d页\n",h,l->pag);
            zh(pt,h,l->pag);
            sc(pt);
            continue;
        }
        if(strcmp(r->op, "存") == 0 && l->singnificenceBit == 1)
            l->modify = 1;
        r = r->next;
    }
}